<!--  -->
<template>
  <div class="model-new">
    <div class="model-new-title">
      <div class="title-ico">
        <img src="@/common/image/new-mirror-ico.png" alt="">
      </div>
      <h2>新建模型</h2>
    </div>
    <div class="conent">
      <el-form
        label-position="top"
        class="form"
        :model="datasetForm"
        :rules="rulesForm"
        ref="datasetForm"
        @submit.native.prevent>
        <el-form-item label="" lable-width="0px" class="form-width-box" prop="name">
          <div class="form-label">模型名称</div>
          <el-input v-model="datasetForm.name" placeholder="名称不能重复，并可以包含字母、数字、横线或下划线"></el-input>
        </el-form-item>
        <el-form-item label="" lable-width="0px" class="form-width-box" prop="introduce">
          <div class="form-label">模型简介</div>
          <el-input
            type="textarea"
            :rows="2"
            v-model="datasetForm.introduce"
            placeholder="建议从使用场景、训练方法、数据集等方面描述您的模型">
          </el-input>
          <!-- <el-input type="textarea" v-model="datasetForm.desc"></el-input> -->
        </el-form-item>
        <div class="radio-wrap">
          <h4 class="form-label">模型文件来源</h4>
          <ul class="form-radio">
            <li class="radio-item radio-itema" :class="[{'active-category': curSelectedMyModel === 0},{'active-left': curSelectedMyModel === 0}]" @click="selectModelType(0)">从任务中选择</li>
            <li class="radio-item radio-items" :class="{'active-category': curSelectedMyModel === 1}" @click="selectModelType(1)">本地上传</li>
          </ul>
          <div class="task">
            <div v-if="curSelectedMyModel === 0">
              <p class="tasp-text">
                将从项目任务中导入训练完成的模型,请您在下方选择需要导入的模型文件. <br>
                您还未创建项目?<span @click="createProject">立即创建</span>
              </p>
              <!-- <el-row :gutter="44">
                <el-col :span="6"><div class="grid-content bg-purple">1</div></el-col>
                <el-col :span="6"><div class="grid-content bg-purple">2</div></el-col>
              </el-row> -->
              <div class="task-select-wra">
                <ul class="task-select">
                  <li class="task-item">
                    <el-select v-model="projectNa" @change="proChange" filterable placeholder="请选择你的项目">
                       <el-option
                         v-for="(item, index) in projectArr"
                         :key="index"
                         :value="item.id"
                         :label="item.projectName"
                         class="task-item-sel">
                         <!-- {{item.projectName}} -->
                       </el-option>
                     </el-select>
                  </li>
                  <li class="task-item">
                    <el-select v-model="taskNa" filterable placeholder="请选择训练任务">
                       <el-option
                         v-for="(item, index) in taskArr"
                         :key="index"
                         :label="item.No"
                         :value="item.id"
                         class="task-item-sel">
                       </el-option>
                     </el-select>
                  </li>
                </ul>
              </div>
            </div>
            <div v-if="curSelectedMyModel === 1">
              <p class="tasp-text">将从本地上传您的模型文件</p>
              <div class="loacl-upload">
                <ul class="upload-items">
                  <li class="item-select">
                    <el-select v-model="language" placeholder="编程语言">
                       <el-option
                         v-for="(item, index) in languageArr"
                         :key="index"
                         :value="item.name">
                       </el-option>
                     </el-select>
                  </li>
                  <li class="item-select">
                    <el-select v-model="algorithm" placeholder="算法框架">
                       <el-option
                         v-for="(item, index) in algorithmArr"
                         :key="index"
                         :value="item.name">
                       </el-option>
                     </el-select>
                  </li>
                </ul>
                <div class="upload-action">
                  <el-button size="medium" class="action-button upload-action-a" @click="clickUploadFile"><i class="icon icon1"></i>上传代码文件</el-button>
                  <span class="right-text">
                    或 <a class="right-text-link" @click="clickUploadFolder">选择文件夹</a>
                  </span>
                </div>
                <div class="file-panel">
                  <div class="file-list" v-show="saveModelFile.length > 0">
                    <ul class="file-item" :class="`file-${file.id}`" v-for="(file, index) in saveModelFile" :key="index">
                      <li class="file-type" v-if="file.directory">
                        <i class="icon-folder"></i>
                      </li>
                      <li class="file-type" v-else>
                        <i class="el-icon-document"></i>
                      </li>
                      <li class="file-name">{{file.fileName}}</li>
                      <li class="file-size">{{file.size ? file.size : '-'}}</li>
                      <li class="file-status"></li>
                      <li class="progress"></li>
                      <li class="file-del" style="opacity: 0"><i class="el-icon-close"></i></li>
                    </ul>
                  </div>
                  <div class="file-list" v-show="uploadFileList.length > 0">
                    <ul class="file-item" :class="`file-${file.id}`" v-for="(file, index) in uploadFileList" :key="index">
                      <li class="file-type">
                        <i class="el-icon-document"></i>
                      </li>
                      <li class="file-name">{{file.name}}</li>
                      <li class="file-size">{{fileSize(file.size)}}</li>
                      <li class="file-status"></li>
                      <li class="progress"></li>
                      <li class="file-del" @click="singleRemoveFile(file, index)"><i class="el-icon-close"></i></li>
                    </ul>
                    <div class="no-file" v-if="!uploadFileList.length"><i class="iconfont icon-empty-file"></i> 暂无待上传文件</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <el-form-item class="submitbtn">
          <el-button class="create-btn" type="primary" @click="submitForm('datasetForm')">保存模型</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 上传文件 -->
    <div id="filePicker" class="upload-location">上传代码文件</div>
    <vue-upload
      ref="uploader"
      uploadButton="#filePicker"
      :url="uploadUrl"
      multiple
      :headers="uploadHeader"
      :fileNumLimit="500"
      @fileChange="fileChange"
      :fileSingleSizeLimit="fileSingleSize"
      :fileSizeLimit="fileSizeLimit"
      @uploadStart="onUploadStart"
      @progress="onProgress"
      @complete="onOnceSuccess"
      @completeAll="onAllSuccess"
      @error="onError"
    ></vue-upload>
    <!-- 上传文件进度条 -->
    <el-dialog
      title=""
      :visible.sync="dialogUploadProcessVisible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :modal="false"
      :show-close="false"
      :lock-scroll="true"
      width="30%">
      <div class="progress-box">
        <el-progress :width="80" type="circle" :percentage="Number(totalProgress)" class="progress-circle"></el-progress>
        <p>正在努力上传数据，请稍后</p>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { createModel, getProName, getJobName } from '@/api/model'
import { copyOutputFileForModel, copyFilesToDataSetOrModel } from '@/api/filecenter'
import { frameworkGetList, languageGetList } from '@/api/image'
import qs from 'qs'
import store from '@/store.js'
import axios from 'axios'
import vueUpload from '@/base/vue-upload'

const WebUploaderObj = window.WebUploader
export default {
  data () {
    var validateName = (rule, value, callback) => {
      var reg1 = /^[a-zA-Z0-9_-]*$/
      var reg2 = /^[a-zA-Z0-9]{1}[a-zA-Z0-9_-]*$/
      if (!reg1.test(value)) {
        callback(new Error('模型名称仅支持字母、数字、横线和下划线'))
      } else if (!reg2.test(value)) {
        callback(new Error('模型名称须以字母或数字开头'))
      } else {
        callback()
      }
    }
    return {
      // 提交状态
      submitStaue: {
        loading: '',
        upload: false,
        submit: false
      },
      // 进度条
      progress: {
        num: 0,
        status: ''
      },
      // 上传文件路径
      uploadUrl: '/gateway/fileCenter/api/file/upload?type=4',
      // 上传文件大小限制
      fileSingleSize: 500 * 1024 * 1024,
      // 限制所有文件大小
      fileSizeLimit: 500 * 1024 * 1024,
      flag: false,
      // 上传文件列表
      uploadFileList: [],
      // 上传状态
      uploadStatus: {},
      // 上传总进度
      totalProgress: 0,
      // 进度 弹窗显示状态
      dialogUploadProcessVisible: false,
      datasetForm: {
        name: '',
        introduce: ''
      },
      rulesForm: {
        name: [
          { required: true, message: '请输入模型名称', trigger: 'blur' },
          { validator: validateName },
          { max: 50, message: '名称长度须在1到50个字符之间' }
        ],
        introduce: [
          { required: true, message: '请输入模型简介', trigger: 'blur' },
          { max: 6000, message: '简介内容不能超过6000个字符' },
          { pattern: /^[\u0020-\u007E\u00A0-\u00BE\u2E80-\uA4CF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF\u0080-\u009F\u2000-\u201f\u2026\u2022\u20ac\r\n]*$/, message: '请勿输入表情字符' }
        ]
      },
      curSelectedMyModel: 0,
      // 语言
      language: '',
      // 算法框架
      algorithm: '',
      // 语言集合
      languageArr: [],
      // 算法框架集合
      algorithmArr: [],
      // 项目 集合
      projectArr: [],
      projectNa: '',
      // 任务集合
      taskArr: [],
      taskNa: '',
      // 文件中心 --> 创建模型
      showCreateByFile: false,
      saveModelFile: []
    }
  },
  components: {
    vueUpload
  },

  computed: {
    // WebUploader对象
    uploader () {
      return this.$refs.uploader
    },
    // 图片上传header
    uploadHeader: () => {
      let obj = {
        token: store.state.userInfo.token,
        bitaToken: store.state.userInfo.bitaToken,
        userId: store.state.userInfo.userId
      }
      return obj
    }
  },

  mounted () {
    this._frameworkGetList()
    this._languageGetList()
    this._getProName()
    this.showCreateByFile = this.$route.query.createByFile
    if (this.showCreateByFile) {
      this.curSelectedMyModel = 1
      this.saveModelFile = JSON.parse(sessionStorage.getItem('saveModelFile'))
      console.log(this.saveModelFile)
    }
  },
  methods: {
    // 获取文件大小
    fileSize (size) {
      return WebUploaderObj.Base.formatSize(size)
    },
    createProject () {
      this.$router.push({ path: '/project/create' })
    },
    onUploadStart (file) {
      let fileDir = ''
      let source = file.source.source
      const rootDir = `/${this.datasetForm.name}`
      if (source.webkitRelativePath) {
        fileDir = rootDir + '/' + source.webkitRelativePath.slice(0, source.webkitRelativePath.lastIndexOf('/' + source.name))
      } else {
        fileDir = rootDir
      }
      let formData = {
        'dir': fileDir
      }
      this.uploader.uploader.options.formData = formData
    },
    onProgress (file, percent) {
      /*
        组件上传进度并不准确，只是说明组件发送文件的进度，可能网络传输和后端仍然在处理中
        暂时处理方式是将进度100%改写为99%，待上传完成时再将进度置为100%
      */
      const uploadStatus = this.uploader.getStats()
      let _percent = percent
      if (Number(_percent.toFixed(2)) === 1.00) {
        _percent = 0.99
      }
      $(`.file-${file.id} .progress`).css('width', _percent * 100 + '%')
      $(`.file-${file.id} .file-status`).html((_percent.toFixed(2) * 100) + '%')
      if (uploadStatus.queueNum === 0 && uploadStatus.successNum === 0) {
        this.totalProgress = (_percent * 100).toFixed(2)
      } else {
        const totalPercent = (((uploadStatus.successNum / (uploadStatus.successNum + uploadStatus.queueNum)) + (1 / (uploadStatus.successNum + uploadStatus.queueNum)) * _percent) * 100).toFixed(2)
        this.totalProgress = Number(totalPercent) > 100 ? 100 : totalPercent
      }
    },
    onOnceSuccess (file, res) {
      $(`.file-${file.id} .progress`).css('width', '100%')
      $(`.file-${file.id} .file-status`).html('100%')
    },
    onAllSuccess () {
      this.dialogUploadProcessVisible = false
      if (this.uploadFileList.length !== 0) this.$message({ message: '上传文件成功', showClose: true, type: 'success' })
      this.$router.push({
        path: '/modellump',
        query: {
          active: 2
        }
      })
    },
    // 上传错误
    onError (msg) {
      // this.uploader.reset()
      this.uploadFileList = []
      this.flag = true
      this.$message({ message: msg, showClose: true, type: 'warning' })
    },
    // 开始上传
    startUpload () {
      this.resume()
    },
    resume (file) {
      this.uploader.upload(file)
    },
    cancleUpload () {
      this.uploader.reset()
    },
    closeUploadDialog () {
      this.uploader.reset()
    },
    fileChange (file) {
      if (!this.flag) {
        this.uploadFileList.push(file)
      }
    },
    // 删除文件1
    singleRemoveFile (file, index) {
      this.uploadFileList.splice(index, 1)
      this.uploader.removeFile(file)
    },
    // 上传文件
    handleUpload () {
      const { fileList } = this
      let _this = this
      let formData = new FormData()
      const fileUrl = '/gateway/fileCenter/api/file/upload'
      // 异步函数
      function async (file, fn) {
        // 拼接文件路径
        const rootDir = `/${this.datasetForm.name}`
        let fileDir = ''
        // 具有webkitRelativePath属性及多级文件路径进行处理
        if (file.webkitRelativePath) {
          if (file.webkitRelativePath.indexOf('/') !== 0) {
            fileDir = rootDir + '/'
          }
        } else {
          fileDir = rootDir
        }

        formData.delete('file')
        formData.delete('dir')
        formData.append('dir', fileDir)
        formData.append('type', 1)
        formData.append('file', file)
        axios({
          method: 'post',
          url: fileUrl,
          headers: { 'Content-Type': 'multipart/form-data' },
          data: formData
        }).then(res => {
          fn()
          // _this.$message({ message: '上传文件成功', showClose: true, type: 'success' })
        }).catch(error => {
          console.log('error', error)
        })
      }
      (function next (i, len, callback) {
        if (i < len) {
          let num_ = i / len
          _this.progress.num = parseInt(num_ * 100)
          async(fileList[i], function (value) {
            next(i + 1, len, callback)
          })
        } else {
          callback()
        }
      })(0, fileList.length, function () {
        _this.submitStaue.upload = true
        if (_this.submitStaue.upload && _this.submitStaue.submit) {
          _this.progress.num = 100
          _this.progress.status = 'success'
          _this.$message({ message: '上传文件成功', showClose: true, type: 'success' })
          // _this.$router.push({ path: '/project/run' })
        }
      })
    },
    // radioTextFun () {
    //   console.log(this.radioText)
    // },
    selectModelType (type) {
      this.curSelectedMyModel = type
    },
    submitForm (agm) {
      this.$refs[agm].validate((valid) => {
        if (valid) {
          // this._createModel()
          if (this.curSelectedMyModel !== 1) {
            if (this.taskNa === '' || this.projectNa === '') {
              this.$message({ message: '请选择文件来源', showClose: true, type: 'warning' })
            } else {
              this._createModel()
            }
          } else {
            this._createModel()
          }
        } else {
          return false
        }
      })
    },
    // 点击上传文件-选择文件
    clickUploadFile () {
      if (this.flag) this.uploader.reset()
      this.flag = false
      document.getElementById('filePicker').getElementsByTagName('input')[0].removeAttribute('webkitdirectory')
      document.getElementById('filePicker').getElementsByTagName('label')[0].click()
    },
    // 点击上传文件-选择文件夹
    clickUploadFolder () {
      if (this.flag) this.uploader.reset()
      this.flag = false
      document.getElementById('filePicker').getElementsByTagName('input')[0].setAttribute('webkitdirectory', '')
      document.getElementById('filePicker').getElementsByTagName('label')[0].click()
    },
    // 项目名称改变
    proChange (val) {
      this.taskArr.length = 0
      this.taskNa = ''
      this._getJobName(val)
    },
    _getProName () {
      getProName().then(res => {
        if (res && res.message && res.message.code === 0) {
          this.projectArr = [...res.data]
          if (this.$route.query.projectId) {
            this.$nextTick(() => {
              this.projectNa = this.idGetName(this.$route.query.projectId)
              // this.projectNa = this.$route.query.projectId
            })
            this._getJobName(this.$route.query.projectId)
          }
        }
      })
    },
    _getJobName (id) {
      let query = `?projectId=${id}`
      getJobName(query).then(res => {
        if (res && res.message && res.message.code === 0) {
          this.taskArr = [...res.data]
          this.taskArr.map(item => {
            item.No = `#${item.codeNo}`
            return item
          })
          if (this.$route.query.jobId) {
            this.$nextTick(() => {
              this.taskNa = this.idGetName2(this.$route.query.jobId)
            })
          }
        }
      })
    },
    _frameworkGetList () {
      frameworkGetList().then(res => {
        if (res.message.code === 0) {
          this.algorithmArr = [...res.data]
          this.algorithm = this.algorithmArr[0].name
        }
      })
    },
    _languageGetList () {
      languageGetList().then(res => {
        if (res.message.code === 0) {
          this.languageArr = [...res.data]
          this.language = this.languageArr[0].name
        }
      })
    },
    // 创建模型
    _createModel () {
      let projectId = ''
      let jobId = ''
      if (this.$route.query.projectId) {
        projectId = this.$route.query.projectId
      } else {
        projectId = this.projectNa ? this.projectNa : ''
      }
      if (this.$route.query.jobId) {
        jobId = this.$route.query.jobId
      } else {
        jobId = this.taskNa ? parseInt(this.taskNa) : ''
      }
      let data = qs.stringify({
        modelName: this.datasetForm.name,
        modelIntroduction: this.datasetForm.introduce,
        projectId,
        jobId,
        language: this.language ? this.language : '',
        framework: this.algorithm ? this.algorithm : '',
        localUpload: this.curSelectedMyModel === 1
      })
      createModel(data).then(res => {
        if (res.message.code === 0) {
          this.$message({ message: '创建模型成功！', showClose: true, type: 'success' })
          if (this.curSelectedMyModel === 1) {
            // 判断是否文件中心 创建模型
            if (this.showCreateByFile) {
              let query = `?type=2&targetDir=/${this.datasetForm.name}`
              this.saveModelFile.forEach(item => {
                query += `&dirs=${item.path}`
              })
              copyFilesToDataSetOrModel(query).then(fileRes => {
                if (res.message.code !== 0) {
                  this.$message({ message: res.message.message, showClose: true, type: 'error' })
                }
              })
            }
            this.dialogUploadProcessVisible = true
            this.resume()
          } else {
            let projectName_ = ''
            let codeNo_ = ''
            if (this.$route.query.projectId) {
              projectName_ = this.idGetName(this.$route.query.projectId)
            } else {
              projectName_ = this.idGetName(this.projectNa)
            }
            if (this.$route.query.jobId) {
              codeNo_ = parseInt(this.idGetName2(this.$route.query.jobId).replace('#', ''))
            } else {
              codeNo_ = parseInt(this.idGetName2(this.taskNa).replace('#', ''))
            }
            let copyData = qs.stringify({
              projectName: projectName_,
              codeNo: codeNo_,
              modelName: this.datasetForm.name
            })
            copyOutputFileForModel(copyData).then(res1 => {
              if (res1.message.code === 20005) {
                // this.$message({ message: 'output目录为空，模型生成失败', showClose: true, type: 'error' })
              } else if (res1.message.code !== 0 && res1.message.code !== 20005) {
                // this.$message({ message: res1.message.message, showClose: true, type: 'error' })
              }
              this.$router.push({
                path: '/modellump',
                query: {
                  active: 2
                }
              })
            })
          }
        } else {
          this.$message({ message: res.message.message, showClose: true, type: 'error' })
        }
      })
    },
    idGetName (id) {
      let name = ''
      this.projectArr && this.projectArr.forEach(item => {
        if (parseInt(item.id) === parseInt(id)) name = item.projectName
      })
      return name
    },
    idGetName2 (id) {
      let name = ''
      this.taskArr && this.taskArr.forEach(item => {
        if (parseInt(item.id) === parseInt(id)) name = item.No
      })
      return name
    }
  }
}

</script>
<style lang="stylus">
@import "../../common/stylus/core/model-new"
$fontcolor = #2D323B
.model-new
  width 100%
  margin 0 auto
  max-width 1162px
  background #999999
  padding-top 103px
  padding-left 134px
  box-sizing border-box
  .model-new-title
    display flex
    padding-bottom 11px
    .title-ico
      width 130px
      height 57px
      margin-right 34px
      img
        width 100%
        height 100%
    h2
      width auto
      font-weight bold
      padding-top 8px
      color $fontcolor
      font-size 28px
      line-height 40px
  .conent
    padding-left 164px
    .form
      .form-width-box
        width 520px
      .form-label
        font-size 14px
        line-height 20px
        color $fontcolor
        padding-bottom 12px
        font-weight bold
      .el-form-item
        padding-bottom 0px
        margin-bottom 24px
      .radio-wrap
        .radiobox
          font-size 14px
          .el-radio-button__inner
            padding 9px 14px
          .el-radio-button__orig-radio:checked+.el-radio-button__inner
            background #E6F1FC
            color #2E94F9
            box-shadow -1px 0 0 0 #dcdfe6
        .form-radio
          width 220px
          display flex
          border-radius 3px
          text-align center
          overflow hidden
          .radio-item
            padding 9px 0
            font-size 14px
            line-height 20px
            color #2D323B
            transition all 0.2s linear
            cursor pointer
          .radio-itema
            width 111px
            border-radius 3px 0 0 3px
            border 1px solid #D1D2D3
            border-right 1px solid #D1D2D3
          .radio-items
            width 107px
            border-radius 0 3px 3px 0
            border 1px solid #D1D2D3
            border-left 0
          .active-category
            background #E6F1FC
            border-color #A3D0FD
            color #2E94F9
          .active-left
            border-right-color #D1D2D3
        .task
          .tasp-text
            font-size 13px
            line-height 20px
            color #808080
            padding 12px 0 20px
            span
              color #2E94F9
              padding-left 8px
              cursor pointer
          .task-select-wra
            width 520px
            padding 24px 22px 22px 12px
            background #F8F9FA
            .task-select
              display flex
              padding-bottom 20px
              justify-content space-between
              .task-item
                width 240px
                font-size 12px
                .el-select
                  width 238px
                .task-item-sel
                  display block
                  width 100%
          .loacl-upload
            width 520px
            padding 24px 64px 24px 22px
            background #F8F9FA
            .upload-items
              display flex
              padding-bottom 20px
              justify-content space-between
              .item-select
                width 200px
            .upload-action
              width 100%
              display flex
              .action-button
                flex 0 0 200px
                .icon
                  display inline-block
                  width 19px
                  height 12px
                  margin-top 1px
                  vertical-align top
                .icon1
                  background url(../../common/image/icon-project/project-edit-box.png) no-repeat center
                  background-size 12px 100%
              .right-text
                flex 1
                padding-left 12px
                line-height 36px
                font-size 14px
      .submitbtn
        padding-top 24px
        .create-btn
          padding 10px 70px
          font-size 16px
          color #FFFFFF
  .upload-location
    display none
  .progress-box
    text-align center
    >p
      font-size 14px
      color #2D323B
      margin-top 18px
</style>
